package org.example.aienglishapp.controller.speech.sentence;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.aienglishapp.controller.speech.dialoguebook.DialogueBookController;
import org.example.aienglishapp.dto.speech.userrecording.UserRecordingDTO;
import org.example.aienglishapp.entity.speech.userrecording.UserRecording;
import org.example.aienglishapp.service.speech.userrecording.UserRecordingService;
import org.example.aienglishapp.util.response.ResponseResult;
import org.example.aienglishapp.util.response.ResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.ObjectMapper;

@RestController
@RequestMapping("/api/speech")
public class AudioController {

    @Autowired
    private UserRecordingService userRecordingService;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    @Qualifier("speechRedisTemplate")
    private RedisTemplate<String, Object> redisTemplate;

    private static final String CACHE_KEY_PREFIX = "user_recording:";
    private static final long CACHE_EXPIRATION = 60 * 60; // 1小时

    private static final Logger logger = LoggerFactory.getLogger(AudioController.class);

    /**
     * 识别并保存用户的录音
     */
    @PostMapping("/recognize")
    public ResponseEntity<String> recognizeSpeech(@RequestParam("file") MultipartFile file,
                                                  @RequestParam("referenceText") String referenceText,
                                                  @RequestParam("userId") Long userId,
                                                  @RequestParam("sentenceId") Long sentenceId,
                                                  @RequestParam("chapterId") Long chapterId) throws IOException {
        try {
            // 构建缓存键
            String cacheKey = CACHE_KEY_PREFIX + userId + ":" + sentenceId + ":" + chapterId;

            // 从缓存中获取UserRecording对象
            String cachedRecordingJson = (String) redisTemplate.opsForValue().get(cacheKey);
            UserRecording cachedRecording = null;
            if (cachedRecordingJson != null) {
                try {
                    cachedRecording = new ObjectMapper().readValue(cachedRecordingJson, UserRecording.class);
                } catch (JsonProcessingException e) {
                    logger.error("Error deserializing UserRecording from cache: " + e.getMessage(), e);
                }
            }

            if (cachedRecording != null) {
                // 如果缓存中存在记录，直接返回识别结果
                Map<String, Object> response = new HashMap<>();
                response.put("sentenceId", cachedRecording.getSentenceId());
                response.put("score", cachedRecording.getScore());
                response.put("textMatchScore", cachedRecording.getTextMatchScore());
                response.put("pitchScore", cachedRecording.getPitchScore());
                response.put("intensityScore", cachedRecording.getIntensityScore());
                response.put("speechRateScore", cachedRecording.getSpeechRateScore());
                return ResponseEntity.ok(new ObjectMapper().writeValueAsString(response));
            }

            // 调用服务层方法
            String recognitionResult = userRecordingService.recognizeAndSaveRecording(file, referenceText, userId, sentenceId, chapterId);

            // 清除相关的缓存
            deleteCache(cacheKey);
            deleteCache(CACHE_KEY_PREFIX + userId);
            deleteCache(CACHE_KEY_PREFIX + "chapter:" + chapterId);
            deleteCache("userRecording:" + userId + ":chapter:" + chapterId);

            // 将识别结果和录音记录存入缓存
            UserRecording userRecording = userRecordingService.getUserRecordingByUserIdAndSentenceId(userId, sentenceId);
            if (userRecording != null) {
                try {
                    // 确保使用 UTF-8 编码
                    String jsonString = new ObjectMapper().writeValueAsString(userRecording);
                    redisTemplate.opsForValue().set(cacheKey, jsonString, CACHE_EXPIRATION, TimeUnit.SECONDS);
                } catch (JsonProcessingException e) {
                    logger.error("Error serializing UserRecording to cache: " + e.getMessage(), e);
                }
            }

            // 构建响应
            Map<String, Object> response = new HashMap<>();
            response.put("sentenceId", sentenceId);
            response.put("score", userRecording.getScore());
            response.put("textMatchScore", userRecording.getTextMatchScore());
            response.put("pitchScore", userRecording.getPitchScore());
            response.put("intensityScore", userRecording.getIntensityScore());
            response.put("speechRateScore", userRecording.getSpeechRateScore());

            return ResponseEntity.ok(new ObjectMapper().writeValueAsString(response));
        } catch (Exception e) {
            logger.error("Error occurred in recognizeSpeech: " + e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error occurred while processing the request");
        }
    }

    /**
     * 根据章节ID获取用户的录音记录
     */
    @GetMapping("/chapter/{chapterId}")
    public ResponseEntity<ResponseResult<List<UserRecording>>> getUserRecordingsByChapterId(
            @PathVariable Long chapterId) {
        // 构建缓存键
        String cacheKey = "userRecording:chapter:" + chapterId;

        // 从缓存中获取UserRecording列表
        String cachedRecordingsJson = (String) redisTemplate.opsForValue().get(cacheKey);
        List<UserRecording> userRecordings = null;
        if (cachedRecordingsJson != null) {
            try {
                userRecordings = new ObjectMapper().readValue(cachedRecordingsJson, new TypeReference<List<UserRecording>>() {});
            } catch (JsonProcessingException e) {
                logger.error("Error deserializing UserRecording list from cache: " + e.getMessage(), e);
            }
        }

        if (userRecordings == null) {
            // 如果缓存中没有记录，从数据库中查询
            userRecordings = userRecordingService.getUserRecordingsByChapterId(chapterId);
            if (userRecordings != null && !userRecordings.isEmpty()) {
                try {
                    // 将查询结果存入缓存
                    String jsonString = new ObjectMapper().writeValueAsString(userRecordings);
                    redisTemplate.opsForValue().set(cacheKey, jsonString, CACHE_EXPIRATION, TimeUnit.SECONDS);
                } catch (JsonProcessingException e) {
                    logger.error("Error serializing UserRecording list to cache: " + e.getMessage(), e);
                }
            } else {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ResponseResult.failed(ResultCode.NOT_FOUND.getCode(), "录音记录不存在"));
            }
        }

        return ResponseEntity.ok(ResponseResult.success(userRecordings));
    }

    /**
     * 获取用户的录音记录
     */
    @GetMapping("/recording")
    public ResponseEntity<ResponseResult<List<UserRecording>>> getUserRecording(@RequestParam("userId") Long userId) {

        // 构建缓存键
        String cacheKey = CACHE_KEY_PREFIX + userId;

        // 从缓存中获取UserRecording列表
        String cachedRecordingsJson = (String) redisTemplate.opsForValue().get(cacheKey);
        List<UserRecording> userRecordings = null;
        if (cachedRecordingsJson != null) {
            try {
                userRecordings = new ObjectMapper().readValue(cachedRecordingsJson, new TypeReference<List<UserRecording>>() {});
            } catch (JsonProcessingException e) {
                logger.error("Error deserializing UserRecording list from cache: " + e.getMessage(), e);
            }
        }

        if (userRecordings == null) {
            // 如果缓存中没有记录，从数据库中查询
            userRecordings = userRecordingService.getUserRecordingByUserId(userId);
            if (userRecordings != null) {
                try {
                    // 将查询结果存入缓存
                    String jsonString = new ObjectMapper().writeValueAsString(userRecordings);
                    redisTemplate.opsForValue().set(cacheKey, jsonString, CACHE_EXPIRATION, TimeUnit.SECONDS);
                } catch (JsonProcessingException e) {
                    logger.error("Error serializing UserRecording list to cache: " + e.getMessage(), e);
                }
            } else {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ResponseResult.failed(ResultCode.NOT_FOUND.getCode(), "录音记录不存在"));
            }
        }

        return ResponseEntity.ok(ResponseResult.success(userRecordings));
    }

    /**
     * 根据用户ID和章节ID获取用户的录音记录
     */
    @GetMapping("/user-chapter")
    public ResponseEntity<ResponseResult<List<UserRecordingDTO>>> getUserRecordingByUserIdAndChapterId(
            @RequestParam("userId") Long userId,
            @RequestParam("chapterId") Long chapterId) {

        // 构建缓存键
        String cacheKey = "userRecording:" + userId + ":chapter:" + chapterId;

        // 从缓存中获取UserRecording列表
        String cachedRecordingsJson = (String) redisTemplate.opsForValue().get(cacheKey);
        List<UserRecording> userRecordings = null;
        if (cachedRecordingsJson != null) {
            try {
                userRecordings = objectMapper.readValue(cachedRecordingsJson, new TypeReference<List<UserRecording>>() {});
            } catch (JsonProcessingException e) {
                logger.error("Error deserializing UserRecording list from cache: " + e.getMessage(), e);
            }
        }

        if (userRecordings == null) {
            // 如果缓存中没有记录，从数据库中查询
            userRecordings = userRecordingService.getUserRecordingByUserIdAndChapterId(userId, chapterId);
            if (userRecordings != null && !userRecordings.isEmpty()) {
                try {
                    // 将查询结果存入缓存
                    String jsonString = objectMapper.writeValueAsString(userRecordings);
                    redisTemplate.opsForValue().set(cacheKey, jsonString, CACHE_EXPIRATION, TimeUnit.SECONDS);
                } catch (JsonProcessingException e) {
                    logger.error("Error serializing UserRecording list to cache: " + e.getMessage(), e);
                }
            } else {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ResponseResult.failed(ResultCode.NOT_FOUND.getCode(), "录音记录不存在"));
            }
        }

        // 转换为DTO
        List<UserRecordingDTO> userRecordingDTOs = userRecordings.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());

        return ResponseEntity.ok(ResponseResult.success(userRecordingDTOs));
    }

    private UserRecordingDTO convertToDTO(UserRecording userRecording) {
        UserRecordingDTO dto = new UserRecordingDTO();
        dto.setRecordingId(userRecording.getRecordingId());
        dto.setUserId(userRecording.getUserId());
        dto.setSentenceId(userRecording.getSentenceId());
        dto.setScore(userRecording.getScore());
        dto.setRecognitionResult(userRecording.getRecognitionResult());
        dto.setTextMatchScore(userRecording.getTextMatchScore());
        dto.setPitchScore(userRecording.getPitchScore());
        dto.setIntensityScore(userRecording.getIntensityScore());
        dto.setSpeechRateScore(userRecording.getSpeechRateScore());
        return dto;
    }
    /**
     * 删除缓存
     */
    private void deleteCache(String cacheKey) {
        redisTemplate.delete(cacheKey);
    }
}